package orbitPrototype.gui;

import java.awt.Rectangle;

import orbitPrototype.loaders.XMLLoader;
import orbitPrototype.objects.Sprite;

/**
 * Description:	Creates a set of sprites, representing the text.
 * @author Drapan
 *
 */
public class GUIText extends GUIElement
{
	public static final String DEFAULT_FONT = "font1";
	public static final String DEFAULT_ADJUSTMENT = "center";
	
	private String _text = "";
	private String _font = DEFAULT_FONT;
	private String _adjustment = DEFAULT_ADJUSTMENT;
	private int _fontPixelSize = 0;
	
	private static final int LETTER_DEFAULT_SPACING = 2;
	private static final int LETTER_SPACE = 6;
		
	/**
	 * Description:	Creates a new GUIText with specified text and default font and adjustment.
	 * @param x
	 * @param y
	 * @param text
	 * @param parentWindow
	 */
	public GUIText(int x, int y, String text, GUIWindow parentWindow)
	{
		super(x, y, 0, 0, parentWindow);
		
		_text = text;
		_fontPixelSize = getFontPixelSize(_font);
		
		setText(_text);
	}

	/**
	 * Description:	Creates a new GUIText with specified text and adjustment and default font.
	 * @param x
	 * @param y
	 * @param text
	 * @param adjustment
	 * @param parentWindow
	 */
	public GUIText(int x, int y, String text, String adjustment, GUIWindow parentWindow)
	{
		super(x, y, 0, 0, parentWindow);
		
		_text = text;
		_fontPixelSize = getFontPixelSize(_font);
		_adjustment = adjustment;
		
		setText(_text);
	}
	
	/**
	 * Description:	Creates a new GUIText with specified text, adjustment and font.
	 * @param x
	 * @param y
	 * @param text
	 * @param font
	 * @param adjustment
	 * @param parentWindow
	 */
	public GUIText(int x, int y, String text, String adjustment, String font, GUIWindow parentWindow)
	{
		super(x, y, 0, 0, parentWindow);
		
		_text = text;
		_font = font;
		_fontPixelSize = getFontPixelSize(_font);
		_adjustment = adjustment;
		
		setText(_text);
	}
	
	
	/**
	 * Description:	Sets fonts and redo's text
	 * @param font
	 */
	public void setFont(String font)
	{
		_font = font;
		_fontPixelSize = getFontPixelSize(_font);
		setText(_text);
	}

	/**
	 * Description:	Clears current text and sets specified one, with default font.
	 * 				Shifts the text to desired (or default) alignment.
	 * @param text
	 */
	public void setText(String text)
	{
		this.clear();
		
		int x = 0;
		
		// Iterate through string and add letters or characters one by one. With spacing inbetween.
		for(int i = 0; i < text.length(); i++)
		{
			String spriteName;
			String alignment;
			
			if(Character.isLetterOrDigit(text.charAt(i)))
			{
				spriteName = String.valueOf(text.charAt(i));
				alignment = getCharHoriziontalAlignment(text.charAt(i));
			}
			else
			{
				spriteName = getResolvedName(text.charAt(i));
				
				if(spriteName.equals("space"))
				{
					x += LETTER_SPACE;
					continue;
				}
				else
				{
					alignment = getCharHoriziontalAlignment(text.charAt(i));
				}
			}
			
			Sprite newLetter = new Sprite(x, 0, _font, spriteName);
			
			if(alignment.equals("center"))
			{
				newLetter.setY(_fontPixelSize / 2);
			}
			else if(alignment.equals("lower"))
			{
				newLetter.setY((_fontPixelSize / 2) - (newLetter.getHeight() / 2));
			}
			
			this.addChild(newLetter);
			x += newLetter.getWidth() + LETTER_DEFAULT_SPACING;
		}
		
		
		// Adjust the entire piece of text
		Rectangle boundingBox = this.getBoundingBox();
		
		if(_adjustment.equals("center"))
		{
			this.shift(-(boundingBox.width / 2), 0);
		}
		else if(_adjustment.equals("left"))
		{
			// This is default state, do nothing.
		}
		else if(_adjustment.equals("right"))
		{
			this.shift(-(boundingBox.width), 0);
		}
		
		this.setWidth(boundingBox.width);
		this.setHeight(boundingBox.height);
	}
	
	/**
	 * Description:	Resolves special characters to string name
	 * @param character
	 * @return
	 */
	private String getResolvedName(char character)
	{
		String resolvedName;
		
		switch (character)
		{
			case ' ':
				resolvedName = "space";
				break;
			case ':':
				resolvedName = "colon";
				break;
			case ';':
				resolvedName = "semicolon";
				break;
			case '.':
				resolvedName = "period";
				break;
			case ',':
				resolvedName = "comma";
				break;
			case '(':
				resolvedName = "parenthessesLeft";
				break;
			case ')':
				resolvedName = "parenthessesRight";
				break;
			case '!':
				resolvedName = "exclamation";
				break;
			case '?':
				resolvedName = "question";
				break;

			default:
				resolvedName = "space";
				break;
		}
		
		return resolvedName;
	}
	
	/**
	 * Description:	Returns to where the character should be aligned horizontally.
	 * @param character
	 * @return
	 */
	private String getCharHoriziontalAlignment(char character)
	{
		String alignment;
		
		switch (character)
		{
			case '(':
			case ')':
			case '!':
			case '?':
			case ':':
			case ';':
				alignment = "upper";
				break;
			case '.':
			case ',':
				alignment = "upper";
				break;
			case '"':
			case '\'':
				alignment = "upper";
				break;

			default:
				alignment = "upper";
				break;
		}
		
		return alignment;
	}
	
	/**
	 * Description:	Returns the largest height of the largest case character of the current font.
	 * @param font
	 * @return
	 */
	public int getFontPixelSize(String font)
	{
		return Integer.parseInt(XMLLoader.getElementValue("height", XMLLoader.getXMLElementByUniqueName("spriteLookup_" + font, "A")));
	}
}
